package com.grape.utils;

import com.grape.constants.Constants;
import com.grape.error.BusinessException;
import com.grape.property.MinioProperty;
import io.minio.*;
import io.minio.messages.Bucket;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component(value = "minioUtils")
@RequiredArgsConstructor
public class MinioUtil implements UploadUtils {

	private static final Logger logger = LoggerFactory.getLogger(MinioUtil.class);

    private final MinioClient minioClient;

	private final MinioProperty minioProperty;

	/**
	 * 创建一个桶
	 */
	public void createBucket(String bucket) throws Exception {
		boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
		if (!found) {
			minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
		}
	}

	/**
	 * 上传一个文件
	 * @param stream		文件流
	 * @param bucket		桶名
	 * @param objectName	对象名
	 * @return				上传后的地址
	 * @throws Exception	异常
	 */
	public String uploadFile(InputStream stream, String bucket, String objectName) throws Exception {
		// 指定contentType: image/jpeg, 默认是流，浏览器打开后下载了无法预览
		minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName)
				.stream(stream, -1, 10485760).contentType(Constants.IMAGE_JPEG).build());
		return minioProperty.getUrl() +  "/" + bucket + "/" + objectName;
	}

	/**
	 * 上传一个文件
	 * @param file			文件对象
	 * @return				上传后的地址
	 * @throws Exception	异常
	 */
	public String upload(MultipartFile file) throws Exception {
		// objectName包含文件名和后缀
		String objectName = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + Constants.SLASH + file.getOriginalFilename();
		// 指定contentType: image/jpeg, 默认是流，浏览器打开后下载了无法预览
        try (InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(PutObjectArgs.builder().bucket(minioProperty.getBuckName()).object(objectName)
                    .stream(inputStream, -1, 10485760).contentType(Constants.IMAGE_JPEG).build());
            return minioProperty.getUrl() + Constants.SLASH + minioProperty.getBuckName() + Constants.SLASH + objectName;
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
	}

	/**
	 * 列出所有的桶
	 * @return				桶列表
	 * @throws Exception	异常
	 */
	public List<String> listBuckets() throws Exception {
		List<Bucket> list = minioClient.listBuckets();
		List<String> names = new ArrayList<>();
		list.forEach(b -> {
			names.add(b.name());
		});
		return names;
	}

	/**
	 * 下载一个文件
	 * @param bucket		桶名
	 * @param objectName	对象名（日期）
	 * @return				输入流
	 * @throws Exception	异常
	 */
	public InputStream download(String bucket, String objectName) throws Exception {
        return minioClient.getObject(
		              GetObjectArgs.builder().bucket(bucket).object(objectName).build());
	}

	/**
	 * 删除一个桶
	 */
	public void deleteBucket(String bucket) throws Exception {
		minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
	}

	/**
	 * 删除一个对象
	 */
	public void deleteObject(String bucket, String objectName) throws Exception {
		minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());
	}
}
